package com.bang.study.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * @Auther: Bang
 * @Date: 2020/8/2 20:05
 * @Description:
 * <p>
 *     EnableAspectJAutoProxy:
 *     		导入了组件 AspectJAutoProxyRegistrar.class这个组件实现了ImportBeanDefinitionRegistrar,注册了一个类
 *     		AnnotationAwareAspectJAutoProxyCreator,这个类主要用来实现aop
 *     		@Import(AspectJAutoProxyRegistrar.class)
 *     		AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar:
 *     			Registers an {@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
 *     		internalAutoProxyCreator = 	AnnotationAwareAspectJAutoProxyCreator
 *     AnnotationAwareAspectJAutoProxyCreator:
 *     		- AspectJAwareAdvisorAutoProxyCreator:
 *     			- AbstractAdvisorAutoProxyCreator:
 *     				- AbstractAutoProxyCreator extends ProxyProcessorSupport:
 *     						implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
 *
 *		AbstractAdvisorAutoProxyCreator: setBeanFactory(BeanFactory beanFactory) =>initBeanFactory()

 *		AnnotationAwareAspectJAutoProxyCreator#initBeanFactory(ConfigurableListableBeanFactory)
 *
 *      AbstractAutoProxyCreator: postProcessBeforeInitialization bean初始化前处理器
 *                                postProcessAfterInitialization  bean初始化前处理器
 *                                postProcessBeforeInstantiation(java.lang.Class, java.lang.String)
 *                                postProcessAfterInstantiation(java.lang.Object, java.lang.String)
 * AOP流程:
 *   1)、传入配置类，创建IOC容器 AnnotationConfigApplicationContext(配置类)
 *      public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
 * 		            this();
 * 		            register(componentClasses);
 * 		            refresh();
 *     }
 *   2)、调用 AbstractApplicationContext#refresh(),刷新容器
 *         2.1) 、Prepare this context for refreshing.
 * 			      prepareRefresh();
 *         2.2) 、Tell the subclass to refresh the internal bean factory.
 * 			     ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 *         2.3) 、Prepare the bean factory for use in this context.
 * 			      prepareBeanFactory(beanFactory);
 *         2.4) 、Allows post-processing of the bean factory in context subclasses.
 * 			      postProcessBeanFactory(beanFactory);
 *         2.5) 、Invoke factory processors registered as beans in the context.
 * 			      invokeBeanFactoryPostProcessors(beanFactory);
 *         2.6) 、 Register bean processors that intercept bean creation.
 *                 (注册所有的bean后置处理器,用来拦截bean的生命周期) -->AnnotationAwareAspectJAutoProxyCreator的创建在这个步骤完成
 *                按照指定的顺序实例化所有的BeanPostProcessor
 * 			      registerBeanPostProcessors(beanFactory);
 * 			      1)、先根据类型获取所有的BeanPostProcessor，并对BeanPostProcessor进行分组 PriorityOrdered,Ordered,普通的
 * 			            List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
 * 		                List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
 * 		                List<String> orderedPostProcessorNames = new ArrayList<>();
 * 		                List<String> nonOrderedPostProcessorNames = new ArrayList<>();
 * 			      2）、priorityOrderedPostProcessors 进行排序,并注册到beanFactory中
 * 			           beanFactory.addBeanPostProcessor(postProcessor);
 *                3）、先从beanFactory中获取对象,获得到对象后放入到orderedPostProcessorNames集合中
 *                     然后对orderedPostProcessorNames 进行排序,并注册到beanFactory中
 *                     ppName=org.springframework.aop.config.internalAutoProxyCreator(AnnotationAwareAspectJAutoProxyCreator)
 *                     BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
 * *                     1)、beanFactory.getBean(ppName, BeanPostProcessor.class)
 *                                      -->AbstractBeanFactory.doGetBean()
 *                                              -->getSingleton(beanName)
 *                                                  --> sharedInstance = getSingleton(beanName, ()->{return createBean(beanName, mbd, args);})
 *                                                  createBean(beanName, mbd, args)即AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args)
 *                                                   -->Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
 *                                                      给BeanPostProcessors一个返回代理而不是目标bean实例的机会.
 *                                                           resolveBeforeInstantiation(){
 *                                                                   bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
 * 					                                                if (bean != null) {
 * 					                                            	    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
 *                                                                  }
 *                                                           }
 *                                                        --> Object beanInstance = doCreateBean(beanName, mbdToUse, args);AbstractAutowireCapableBeanFactory.doCreateBean(beanName, mbdToUse, args)
 *                                                              (1) 创建bean对象. Object bean = instanceWrapper.getWrappedInstance();
 *                                                              (2) populateBean(beanName, mbd, instanceWrapper); bean的属性赋值
 *                                                              (3) exposedObject = initializeBean(beanName, exposedObject, mbd); 初始化bean实例
 *                                                                  (3.1) invokeAwareMethods(beanName, bean); 调用BeanNameAware,BeanClassLoader,AwareBeanFactoryAware接口的方法
 *                                                                  (3.2) applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 在初始化之前应用Bean后处理器
 *                                                                      (3.2.1) 获得所有的BeanPostProcessors
 *                                                                      (3.2.2) 循环调用postProcessBeforeInitialization()方法
 *                                                                  (3.3) invokeInitMethods(beanName, wrappedBean, mbd);
 *                                                                      (3.3.1) 调用InitializingBean.afterPropertiesSet()
 *                                                                      (3.3.2) 调用自定义的init方法
 *                                                                  (3.4) applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 *                                                                      (3.4.1) 获得所有的BeanPostProcessors
 *                                                                      (3.4.1) 循环调用postProcessAfterInitialization()方法
 *                       internalAutoProxyCreator初始化完成后放入单例池中 DefaultSingletonBeanRegistry.addSingleton(beanName, bean)
 *
 *                4）、nonOrderedPostProcessorNames 注册到beanFactory中
 *                5）、internalPostProcessors进行排序 注册到beanFactory中 (MergedBeanDefinitionPostProcessor)
 *          至此 AnnotationAwareAspectJAutoProxyCreator 创建完成并放入到了beanFactory中
 *
 *         2.7) 、Initialize message source for this context.
 * 			      initMessageSource();
 *         2.8) 、Initialize event multicaster for this context.
 * 			      initApplicationEventMulticaster();
 *         2.9) 、Initialize other special beans in specific context subclasses.
 * 			      onRefresh();
 *         2.10) 、Check for listener beans and register them.
 * 			      registerListeners();
 *         2.11) 、实例化所有剩余的（非延迟初始化）单例。 (在此方法中对所有剩下的单实例bean就行初始化)
 * 			      finishBeanFactoryInitialization(beanFactory); --> 在bean的实例化过程中判断是否需要被代理
 *
 *         2.12) 、Last step: publish corresponding event.
 * 			      finishRefresh();
 *
 *
 * </p>
 */
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(value ={ "com.bang.study.aop", "com.bang.study.proxy"})
public class AopConfig {
}
